﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Xml;
using System.Xml.Linq;
using ALinq;
using ALinq.BBS.DataAccess;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            //var root = Board.CreateRootInstance();
            var db = new Database(@"D:\SureMai\WebSite\App_Data\ALinqBBS.db3");
            db.Log = Console.Out;
            //foreach (var board in db.Boards)
            //{
                foreach (var user in db.Users)
                {
                    var postsCount = db.Posts.Count(o => o.UserID == user.ID);
                    db.Users.Update(o => new User { PostsCount = postsCount }, 
                                    o => o.ID == user.ID);
                }
            //}
            //db.SubmitChanges();
        }
    }

    class XMappingDatabase<T>
    {
        public XMappingDatabase(XElement element)
        {
            this.Element = element;
        }

        public XElement Element { get; private set; }

        public string Provider
        {
            get
            {
                var attribute = Element.Attribute("Provider");
                if (attribute == null)
                    return null;
                return attribute.Value;
            }
            set
            {
                var attribute = Element.Attribute("Provider");
                if (attribute == null)
                    Element.SetAttributeValue("Provider", value);
                else
                    attribute.Value = value;
            }
        }
    }

    class XMappingType<T>
    {
        public XMappingType(XElement element)
        {
            this.Element = element;
        }

        public XElement Element { get; private set; }
    }

    class XMappingColumn
    {
        public XMappingColumn(XElement element)
        {
            this.Element = element;
        }

        public XElement Element { get; private set; }

        public string DbType
        {
            get
            {
                var attribute = Element.Attribute("DbType");
                if (attribute == null)
                    return null;
                return attribute.Value;
            }
            set
            {
                var attribute = Element.Attribute("DbType");
                if (attribute == null)
                    Element.SetAttributeValue("DbType", value);
                else
                    attribute.Value = value;
            }
        }
    }

    static class XmlMappingSourceUtility
    {
        public static XMappingType<TEntity> Type<TSource, TEntity>(this XMappingDatabase<TSource> source, Expression<Func<TSource, Table<TEntity>>> predicate) where TEntity : class
        {
            var name = typeof(TEntity).FullName;

            var element = source.Element.Descendants().Where(o => o.Name.LocalName == "Type")
                                                      .Where(o => o.Attribute("Name") != null && o.Attribute("Name").Value == name).SingleOrDefault();
            if (element == null)
                throw new Exception(string.Format("Count Not Found the '{0}' Element in the XDocument", name));

            return new XMappingType<TEntity>(element);
        }

        public static XMappingColumn Column<TSource>(this XMappingType<TSource> source, Expression<Func<TSource, object>> predicate)
        {
            var parameters = predicate.Parameters;
            var name = ((MemberExpression)predicate.Body).Member.Name;

            var element = source.Element.Descendants().Where(o => o.Name.LocalName == "Column")
                                                        .Where(o => o.Attribute("Name") != null && o.Attribute("Name").Value == name).SingleOrDefault();
            if (element == null)
                throw new Exception(string.Format("Count Not Found the '{0}' Element in the XDocument", name));

            return new XMappingColumn(element);
        }

        public static XMappingDatabase<TSource> CreateFrom<TSource>(StreamReader reader)
        {
            var doc = XElement.Load(reader, LoadOptions.None);
            return new XMappingDatabase<TSource>(doc);
        }

    }

}
